import json
import os
import time
import uuid
import random

import requests


def read_all_files(path='../data'):
    return os.listdir(path)


def to_json(files: list, base_dir):
    files.sort()
    out = []
    for idx, file in enumerate(files):
        out.append({'title': file, 'index': idx})
        os.rename(f"{base_dir}/{file}", f"{base_dir}/{str(idx)}.mp4")

    with open('../data/record/data.json', mode='w') as f:
        json.dump(out, f)


proxies = {
    'http': 'http://localhost:7890',
    'https': 'http://localhost:7890',
}


def query(filename):
    API_URL = "https://api-inference.huggingface.co/models/jonatasgrosman/wav2vec2-large-xlsr-53-english"
    headers = {"Authorization": "Bearer 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"}

    with open(filename, "rb") as f:
        data = f.read()
    response = requests.post(API_URL, headers=headers, data=data, proxies=proxies)
    return response.json()


def speech_to_text(speech_path='../data/record/blob.wav'):
    return query(speech_path)


def query_dilog(payload):
    API_URL = "https://api-inference.huggingface.co/models/microsoft/DialoGPT-large"
    headers = {"Authorization": "Bearer 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"}
    response = requests.post(API_URL, headers=headers, json=payload, proxies=proxies)
    return response.json()


def generate_dialog(payload):
    return query_dilog(payload)


def text_to_speech(payload: dict):
    """
    :param payload:{"inputs":"The answer to the universe is 42"}
    :return:
    """
    API_URL = "https://api-inference.huggingface.co/models/facebook/fastspeech2-en-ljspeech"
    headers = {"Authorization": "Bearer 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"}
    response = requests.post(API_URL, headers=headers, json=payload, proxies=proxies)
    uid = uuid.uuid4().hex
    try:
        d = json.loads(response.content)

        while d.get('estimated_time',None) is not None:
            time.sleep(d['estimated_time']-10)
            response = requests.post(API_URL, headers=headers, json=payload, proxies=proxies)
            d = json.loads(response.content)
            print(d)
    except Exception as e:
        pass
    with open(f'data/generated/{uid}.wav', mode='w+b') as f:

        f.write(response.content)
    return uid


def talk_to_huggingface_chat(text):
    API_URL = "https://huggingface.co/chat/conversation"
    user_agent_list = [
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95',
        'Safari/537.36 OPR/26.0.1656.60',
        'Opera/8.0 (Windows NT 5.1; U; en)',
        'Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50',
        'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0',
        'Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 '
        '(maverick) Firefox/3.6.10',
        'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
        'Chrome/39.0.2171.71 Safari/537.36',
        'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 '
        '(KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
    ]
    URL = "https://huggingface.co/chat/settings"
    # payload = {'ethicsModalAccepted': True,'shareConversationsWithModelAuthors': True,
    #            'ethicsModalAcceptedAt': '','activeModel': 'OpenAssistant/oasst-sft-6-llama-30b-xor'}

    cookie = {
    "hf-chat": "228a2222-c38b-4765-812b-2a06eebc0bdc",
    "_ga": "GA1.1.53085295.1684904164",
    "_ga_8Q63TH4CSL": "GS1.1.1685366708.10.1.1685366712.0.0.0",
    "__stripe_mid": "966c2fa1-ba8c-459a-ac56-9da721c03da1491117",
    "token": "MevWfIGNCsASSYABvfYNYKqUOJWwHwPvLQrzlLquXGjyUfmYeGUIzXAYqOqifSheMrZWknLNiaRiMBIswLcEHhZFAOrauyJgEwlKoohVWOtoeLkCHBQQeInLyZJliYNn"
}
    payload = {
        "inputs": text,
        "parameters": {
            "temperature": 0.9,
            "truncate": 30,
            "max_new_tokens": 1024,
            "stop": [
                "</s>"
            ],
            "top_p": 0.95,
            "repetition_penalty": 1.2,
            "top_k": 50,
            "return_full_text": False
        },
        "stream": True,
        "options": {
            "id": "1e9c556a-ec77-487d-9751-7083526bf769",
            "is_retry": False,
            "use_cache": False
        }
    }
    UserAgent = random.choice(user_agent_list)
    header = {'User-Agent': UserAgent}
    try:
        response = requests.post("https://huggingface.co/chat/conversation/646335864633331e54c9f713", headers=header, proxies=proxies, json=payload, cookies=cookie)
        res = [i for i in response.text.split('\n\n') if i != '']
        rep = json.loads("{" + res[-1].replace('data', '"data"') + "}")
        generated_text = rep['data']['generated_text']
    except Exception:
        generated_text = "Sorry, something went wrong. Please try again."
    return generated_text


from datetime import datetime
from wsgiref.handlers import format_date_time
import hmac
import hashlib
import base64
from urllib.parse import urlencode
import _thread as thread
import websocket

STATUS_FIRST_FRAME = 0
STATUS_CONTINUE_FRAME = 1
STATUS_LAST_FRAME = 2

class Ws_Param(object):
    def __init__(self,APPID,APIKey,APISecret,AudioFile,Text) -> None:
        self.APPID = APPID
        self.APIKey = APIKey
        self.APISecret = APISecret
        self.AudioFile = AudioFile
        self.Text = Text
        SUB = "ise"
        ENT = "en_vip"
        CATEGORY = "read_word"
        self.CommonArgs = {"app_id": self.APPID}
        self.BusinessArgs = {"category":CATEGORY,
                             "sub":SUB,
                             "ent":ENT,
                             "cmd":"ssb",
                             "aue": "raw", "auf": "audio/L16;rate=16000", 
                             "text": self.Text, "ttp_skip": True,"aus":1}
    def create_url(self):
        url = "wss://ise-api.xfyun.cn/v2/open-ise"
        now = datetime.now().timestamp()
        date = format_date_time(now)
        signature_origin = "host: " + "ise-api.xfyun.cn" + "\n"
        signature_origin += "date: " + date + "\n"
        signature_origin += "GET " + "/v2/open-ise" + " HTTP/1.1"
        signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'), digestmod=hashlib.sha256).digest()
        signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')
        
        authorization_origin = f'api_key="{self.APIKey}",algorithm="hmac-sha256",headers="host date request-line",signature="{signature_sha}"'
        authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
        v = {
            "authorization": authorization,
            "date": date,
            "host": "ise-api.xfyun.cn"
        }
        url = url + '?' + urlencode(v)
        return url



import xml.etree.ElementTree as ET

def parse_xml(xml_content:str):
    out = []
    root = ET.fromstring(xml_content)
    for word in root.iter('word'):
        attr = word.attrib
        if attr.get('content',None) is not None:
            out.append({'content':attr['content'],'total_score':attr['total_score']})
    return out

import ssl
def initial_and_send(APPID,APIKey,APISecret,AudioFile,Text,filename):
    time1 = datetime.now()
    websocket.enableTrace(False)
    Text = "\uFEFF" + open(Text, "r", encoding="utf-8").read()

    wsParam = Ws_Param(APPID=APPID, APIKey=APIKey, APISecret=APISecret, AudioFile=AudioFile, Text=Text)
    wsUrl = wsParam.create_url()

    def on_open(ws):
        def run(*args):
            frameSize = 1280
            intervel = 0.04
            status = STATUS_FIRST_FRAME
            with open(wsParam.AudioFile, "rb") as fp:
                while True:
                    buf = fp.read(frameSize)
                    if not buf:
                        status = STATUS_LAST_FRAME
                    if status == STATUS_FIRST_FRAME:
                        print('send first frame')
                        d = {"common": wsParam.CommonArgs,
                                "business": wsParam.BusinessArgs,
                                "data":{"status":0}}
                        d = json.dumps(d)
                        ws.send(d)
                        status = STATUS_CONTINUE_FRAME
                    elif status == STATUS_CONTINUE_FRAME:
                        print('send continue frame')
                        d = {"business":{"cmd":"auw", "aus":2, "aue": "raw"},
                                "data":{"status":1, "data":str(base64.b64encode(buf), 'utf-8')}}
                        ws.send(json.dumps(d))
                    elif status == STATUS_LAST_FRAME:
                        print('send last frame')
                        d = {"business":{"cmd":"auw", "aus":4, "aue": "raw"},
                                "data":{"status":2, "data":str(base64.b64encode(buf), 'utf-8')}}
                        ws.send(json.dumps(d))
                        time.sleep(1)
                        break

                    time.sleep(intervel)
            ws.close()

        thread.start_new_thread(run, ())   

    def on_error(ws, error):
        print("### error ###")
        print(error)     

    def on_message(ws, message):
        try:
            code = json.loads(message)["code"]
            sid = json.loads(message)["sid"]
            if code != 0:
                errMsg = json.loads(message)["message"]
                print("sid:%s call error:%s code is:%s" % (sid, errMsg, code))
            else:
                data = json.loads(message)["data"]
                status = data["status"]
                result = data["data"]
                print(message)
                if status == 2:
                    xml = base64.b64decode(result)
                    xml = xml.decode('utf-8')
                    try:
                        with open('./score/score/'+filename+'.xml','w') as f:
                            f.write(xml)
                            result = parse_xml(xml)
                            print(xml)
                            ws.close()
                    except Exception as e:
                        print("write file error",e)

        except Exception as e:
            print("receive msg,but parse exception:", message,"exception=",e)

    def on_close(ws):
        print("### closed ###")
        
    ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close)
    ws.on_open = on_open
    ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
    time2 = datetime.now()
    print(time2-time1)
    




if __name__ == '__main__':
    print(talk_to_huggingface_chat('who are you '))
    # content = open('./score/score/111222.xml','r',encoding='utf-8').readlines()
    # content = ''.join(content[1:])
    # print(os.path.abspath('.'))
    # print(parse_xml(content))
    # APPID = "ccf4321c"
    # APIKey = "3ec5b91ea42617578a40cd20918e80c5"
    # APISecret = "NTFmOWZmYTMzNjRkYzcyMmMyZDI5MTM0"
    # initial_and_send(APPID,APIKey,APISecret,"/Users/jan/Desktop/en/fastApiProject/score/audio/d6ef3c23adbc4f5c96ea055c02597673.wav",
    #                  "/Users/jan/Desktop/en/fastApiProject/score/word/d6ef3c23adbc4f5c96ea055c02597673.txt",filename='111222')
    # initial_and_send(APPID,APIKey,APISecret,"/Users/jan/Desktop/en/en/read_word_en.pcm",
                    #  "/Users/jan/Desktop/en/en/read_sentence_en.txt",filename='111222')
    # initial_and_send(APPID,APIKey,APISecret,"/Users/jan/Desktop/en/en/read_sentence_en.pcm",
                    #  "/Users/jan/Desktop/en/en/read_sentence_en.txt",filename='111222')

    # initial_and_send(APPID,APIKey,APISecret,"../en/read_sentence_en.pcm",
    #                  "../en/read_sentence_en.txt",filename='111222')